package com.adamfass.tractorbeam.gameupdatelogic;

import java.util.Set;

import com.adamfass.tractorbeam.PhysicsGameObject;
import com.jme.math.Vector3f;
import com.jme.scene.Node;
import com.jme.scene.shape.Box;

public class DisruptorPodTargeter {
  private final Node rootNode;
  private final PhysicsGameObject shooter;
  private final Set<TractorBeamRecord> tractorBeamRecordSet;
  
  /**
   * Current target position, null if there is none.
   */
  private Vector3f targetPosition = null;
  
  /**
   * Current target normal, null if there is none.
   */
  private Vector3f targetNormal = null;
  
  private final Node crosshairs;
  private boolean crosshairsAttached;
  
  public DisruptorPodTargeter(
      Node rootNode, 
      PhysicsGameObject shooter, 
      Set<TractorBeamRecord> tractorBeamRecordSet) {
    this.rootNode = rootNode;
    this.shooter = shooter;
    this.tractorBeamRecordSet = tractorBeamRecordSet;
  
    crosshairs = new Node();
    final Box horizontal = new Box("crosshairs horizontal", Vector3f.ZERO, 10, 1, 1);
    final Box vertical = new Box("crosshairs vertical", Vector3f.ZERO, 1, 10, 1);
    crosshairs.attachChild(horizontal);
    crosshairs.attachChild(vertical);
    crosshairsAttached = false;
  }
  
  public final void update() {
    // Find the target position and normal.
    targetPosition = null;
    targetNormal = null;
    float targetDistance = Float.MAX_VALUE;
    
    for (TractorBeamRecord record : tractorBeamRecordSet) {
      // Ignore the shooter's own tractor beam.
      if (record.shooter == shooter) {
        continue;
      }
      
      Vector3f shooterToTarget = record.target.getPosition().subtract(
          record.shooter.getPosition());
      Vector3f beamMidpoint = record.shooter.getPosition().add(
          shooterToTarget.mult(0.5f));
      float beamDistance = shooter.getPosition().distance(beamMidpoint);
      if (beamDistance < targetDistance) {
        targetPosition = beamMidpoint;
        targetNormal = shooterToTarget.normalizeLocal();
      }
    }
    
    // Draw or remove targeting feedback.
    if (targetPosition != null) {
      if (!crosshairsAttached) {
        rootNode.attachChild(crosshairs);
        crosshairsAttached = true;
      }
      crosshairs.setLocalTranslation(targetPosition);
      crosshairs.updateGeometricState(0, true);
    } else if (crosshairsAttached) {
      crosshairs.removeFromParent();
      crosshairsAttached = false;
    }
  }
  
  public Vector3f getTargetPosition() {
    return targetPosition;
  }
  
  public Vector3f getTargetNormal() {
    return targetNormal;
  }
}
